/*
 * Copyright (c) 2024 BI1NDG_Zhouyuling AND BI1NDF_Duanyuyan
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//库函数
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_i2c.h"
#include "iot_gpio.h"
#include "iot_uart.h"
#include "iot_gpio_ex.h"
#include "iot_errno.h"
#include "oled_ssd1306.h"
#include "common_def.h"
#include "osal_debug.h"
#include "osal_task.h"
#include "securec.h"
#include "sle_device_discovery.h"
#include "sle_connection_manager.h"
#include "sle_ssap_client.h"
#include "SLE_CONTROLLER.h"
#include "sle_errcode.h"
#include "ohos_sle_common.h"
#include "ohos_sle_errcode.h"
#include "ohos_sle_ssap_server.h"
#include "ohos_sle_ssap_client.h"
#include "ohos_sle_device_discovery.h"
#include "ohos_sle_connection_manager.h"
#include "iot_uart.h"
#include "pinctrl.h"
#include "uart.h"
#include "errcode.h"

//按键设置
#define SWITCH_PIN 10

//I2C设置
#define AHT20_BAUDRATE (400 * 1000)
#define AHT20_I2C_IDX 1

//蜂鸣器设置
#define BEEP_PIN 12

//LED设置
#define LED_PIN 14

//GPS设置
#define Satellite_RX_PIN 7
#define Satellite_TX_PIN 8
#define Satellite_RATE 9600
#define Satellite_DATABITS 3
#define Satellite_STOPBITS 1
#define Satellite_PARITYBIT 0
#define Satellite_SIZE 256
#define Satellite_BUSID 2
static uint8_t ReadBuff[Satellite_SIZE];
static uint8_t Satellite_NUM=0;
static char CONTROLER_latitude[16] = {0};
static char CONTROLER_longitude[16] = {0};
static char CONTROLER_SLE_latitude[16] = {0};
static char CONTROLER_SLE_longitude[16] = {0};
static char SLE_latitude[16] = {0};
static char SLE_longitude[16] = {0};

//时钟设置
#define DELAY_100MS 100
#define DELAY_200MS 200
#define DELAY_500MS 500
#define DELAY_1000MS 1000
#define DELAY_2000MS 2000
#define DELAY_3000MS 3000
#define DELAY_5000MS 5000
#define DELAY_10000MS 10000

//SLE设置
#define SLE_MTU_SIZE_DEFAULT 512
#define SLE_SEEK_INTERVAL_DEFAULT 100
#define SLE_SEEK_WINDOW_DEFAULT 100
#define UUID_16BIT_LEN 2
#define UUID_128BIT_LEN 16
#define SLE_UART_TASK_DELAY_MS 1000
#define SLE_UART_WAIT_SLE_CORE_READY_MS 5000
#define SLE_UART_SERVER_NAME "BEACON_BI1NDF"
#define SLE_CONTROLLER_LOG                     "[SLE_CONTROLLER]"
#define UUID_LEN_2     2
static char g_sle_uuid_app_uuid[] = { 0x39, 0xBE, 0xA8, 0x80, 0xFC, 0x70, 0x11, 0xEA, 0xB7, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static unsigned char uartReadBuff[100];
static ssapc_find_service_result_t g_sle_uart_find_service_result = { 0 };
static sle_announce_seek_callbacks_t g_sle_uart_seek_cbk = { 0 };
static SleConnectionCallbacks g_sle_uart_connect_cbk = { 0 };
static ssapc_callbacks_t g_sle_uart_ssapc_cbk = { 0 };
static SleAddr g_sle_uart_remote_addr = { 0 };
ssapc_write_param_t g_sle_uart_send_param = { 0 };
uint16_t g_sle_uart_conn_id = 0;
uint8_t g_client_id = 0;
static uint8_t g_at_pre_char = 0;
static uint32_t g_at_uart_recv_cnt = 0;
#define SLE_UART_TRANSFER_SIZE              256
static uint8_t g_app_uart_rx_buff[SLE_UART_TRANSFER_SIZE] = { 0 };
static uart_buffer_config_t g_app_uart_buffer_config = {.rx_buffer = g_app_uart_rx_buff, .rx_buffer_size = SLE_UART_TRANSFER_SIZE};

static void OnButtonPressed(char *arg)
{
    (void)arg;
    //printf("SOSCall\r\n");
    uart_sle_client_send_data("SOSCall",16);
}

static void SOSCall()
{
    // 初始化GPIO
    IoTGpioInit(BEEP_PIN);
    IoTGpioInit(LED_PIN);
    // 设置引脚功能为MODE_0(GPIO)
    IoSetFunc(BEEP_PIN, IOT_IO_FUNC_GPIO_12_GPIO);
    IoSetFunc(LED_PIN, IOT_IO_FUNC_GPIO_14_GPIO);
    // 设置GPIO为输出方向
    IoTGpioSetDir(BEEP_PIN, IOT_GPIO_DIR_OUT);
    IoTGpioSetDir(LED_PIN, IOT_GPIO_DIR_OUT);
    // 配置GPIO引脚号和输出值
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    //S
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    //O
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_500MS);
    //S
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_5000MS);
    //S
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    //O
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_500MS);
    //S
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_5000MS);
    //S
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    //O
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_500MS);
    //S
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_5000MS);
    return NULL; 
}

static void Satellite_RX_callback(const void *buffer, uint16_t length, bool error)
{
    TaskMsleep(DELAY_10000MS);
    //printf("Satellite_BUFFER:%s\r\n", (const char *)buffer);
    if(strncmp((const char *)buffer, "$GNGGA", 6) == 0)
    {
        ReadBuff[0] = '\0';
        Satellite_NUM = 0;
    }
    if(Satellite_NUM<5)
    {
        strncat(ReadBuff, buffer, length);
        Satellite_NUM = Satellite_NUM+1;
    }
    else
    {
        //printf("Satellite_ReadBuffer:%s\r\n", ReadBuff);
        char latitude[16] = {0};
        char longitude[16] = {0};
        const char *ptr = (char *)ReadBuff + 7;
        ptr = strchr(ptr, ',') + 1;
        char *lat_end = strchr(ptr, ',');
        strncpy(latitude, ptr, lat_end - ptr);
        latitude[lat_end - ptr] = '\0';
        ptr = lat_end + 3;
        char *lon_end = strchr(ptr, ',');
        strncpy(longitude, ptr, lon_end - ptr);
        longitude[lon_end - ptr] = '\0';
        //printf("+++Latitude+++\r\n");
        if(strcmp(latitude,CONTROLER_SLE_latitude)!=0)
        {
            //printf("Latitude: %s\r\n", latitude);
            strcpy(CONTROLER_latitude, "LAT:");
            strncat(CONTROLER_latitude, latitude, 16);
            strcpy(CONTROLER_SLE_latitude,latitude);
        }
        //printf("+++longitude+++\r\n");
        if(strcmp(longitude,CONTROLER_SLE_longitude)!=0)
        {
            //printf("Longitude: %s\r\n", longitude);
            strcpy(CONTROLER_longitude, "LON:");
            strncat(CONTROLER_longitude, longitude, 16);
            strcpy(CONTROLER_SLE_longitude,longitude);
        }
    }
}

static void Satellite_config()
{
    uapi_uart_deinit(2);
    IotUartAttribute g_uart_cfg = {9600, 8, 1, IOT_UART_PARITY_NONE, 100, 100, 0}; 
    IoTUartInit(2, &g_uart_cfg);
    (void)uapi_uart_register_rx_callback(2, UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE, Satellite_SIZE, Satellite_RX_callback);
}

uint16_t get_g_sle_uart_conn_id(void)
{
    return g_sle_uart_conn_id;
}

ssapc_write_param_t *get_g_sle_uart_send_param(void)
{
    return &g_sle_uart_send_param;
}

static void uart_rx_callback(const void *buffer, uint16_t length, bool error)
{
    errcode_t ret;
    if(length > 0)
    {
        ret = uart_sle_client_send_data((uint8_t *)buffer,(uint8_t)length);
        if(ret != 0)
        {
            osal_printk("\r\nsle_client_send_data_fail:%d\r\n", ret);
        }
    }
}

static void uart_init_config(void)
{
    uart_attr_t attr = {.baud_rate = 115200, .data_bits = UART_DATA_BIT_8, .stop_bits = UART_STOP_BIT_1, .parity = UART_PARITY_NONE};
    uart_pin_config_t pin_config = {.tx_pin = 0, .rx_pin = 0, .cts_pin = PIN_NONE, .rts_pin = PIN_NONE};
    uapi_uart_deinit(0);
    uapi_uart_init(0, &pin_config, &attr, NULL, &g_app_uart_buffer_config);
    (void)uapi_uart_register_rx_callback(0, UART_RX_CONDITION_FULL_OR_IDLE, 1, uart_rx_callback);
}

void sle_uart_start_scan(void)
{
    SleSeekParam param = { 0 };
    param.ownaddrtype = 0;
    param.filterduplicates = 0;
    param.seekfilterpolicy = 0;
    param.seekphys = 1;
    param.seekType[0] = 1;
    param.seekInterval[0] = SLE_SEEK_INTERVAL_DEFAULT;
    param.seekWindow[0] = SLE_SEEK_WINDOW_DEFAULT;
    SleSetSeekParam(&param);
    SleStartSeek();
}

static void sle_uart_client_sample_sle_enable_cbk(errcode_t status)
{
    if (status != 0)
    {
        osal_printk("%s sle_uart_client_sample_sle_enable_cbk,status error\r\n", SLE_CONTROLLER_LOG);
    }
    else
    {
        osal_msleep(SLE_UART_TASK_DELAY_MS);
        sle_uart_start_scan();
    }
}

static void sle_uart_client_sample_seek_enable_cbk(errcode_t status)
{
    if (status != 0)
    {
        osal_printk("%s sle_uart_client_sample_seek_enable_cbk,status error\r\n", SLE_CONTROLLER_LOG);
    }
}

static void sle_uart_client_sample_seek_result_info_cbk(SleSeekResultInfo *seek_result_data)
{
    osal_printk("%s sle uart scan data :%s\r\n", SLE_CONTROLLER_LOG, seek_result_data->data);
    if (seek_result_data == NULL)
    {
        osal_printk("status error\r\n");
    } 
    else if (strstr((const char *)seek_result_data->data, SLE_UART_SERVER_NAME) != NULL)
    {
        memcpy_s(&g_sle_uart_remote_addr, sizeof(sle_addr_t), &seek_result_data->addr, sizeof(sle_addr_t));
        SleStopSeek();
    }
}

static void sle_uart_client_sample_seek_disable_cbk(errcode_t status)
{
    if (status != 0)
    {
        osal_printk("%s sle_uart_client_sample_seek_disable_cbk,status error = %x\r\n", SLE_CONTROLLER_LOG, status);
    }
    else
    {
       SleConnectRemoteDevice(&g_sle_uart_remote_addr);
    }
}

static void sle_uart_client_sample_seek_cbk_register(void)
{
    g_sle_uart_seek_cbk.sle_enable_cb = sle_uart_client_sample_sle_enable_cbk;
    g_sle_uart_seek_cbk.seek_enable_cb = sle_uart_client_sample_seek_enable_cbk;
    g_sle_uart_seek_cbk.seek_result_cb = sle_uart_client_sample_seek_result_info_cbk;
    g_sle_uart_seek_cbk.seek_disable_cb = sle_uart_client_sample_seek_disable_cbk;
    sle_announce_seek_register_callbacks(&g_sle_uart_seek_cbk);
}

static void sle_uart_client_sample_connect_state_changed_cbk(uint16_t conn_id, const SleAddr *addr, SleAcbStateType conn_state, SlePairStateType pair_state, SleDiscReasonType disc_reason)
{
    unused(addr);
    unused(pair_state);
    osal_printk("%s conn state changed disc_reason:0x%x\r\n", SLE_CONTROLLER_LOG, disc_reason);
    g_sle_uart_conn_id = conn_id;
    if (conn_state == SLE_ACB_STATE_CONNECTED)
    {
        osal_printk("%s SLE_ACB_STATE_CONNECTED\r\n", SLE_CONTROLLER_LOG);
        SsapcExchangeInfo info = {0};
        info.mtuSize = SLE_MTU_SIZE_DEFAULT;
        info.version = 1;
        SsapcExchangeInfoReq(0, conn_id, &info);
    }
    else if (conn_state == SLE_ACB_STATE_NONE)
    {
        osal_printk("%s SLE_ACB_STATE_NONE\r\n", SLE_CONTROLLER_LOG);
    }
    else if (conn_state == SLE_ACB_STATE_DISCONNECTED)
    {
        osal_printk("%s SLE_ACB_STATE_DISCONNECTED\r\n", SLE_CONTROLLER_LOG);
        sle_uart_start_scan();
    }
    else
    {
        osal_printk("%s status error\r\n", SLE_CONTROLLER_LOG);
    }
}

static void sle_uart_client_sample_connect_cbk_register(void)
{
    g_sle_uart_connect_cbk.connectStateChangedCb = sle_uart_client_sample_connect_state_changed_cbk;
    SleConnectionRegisterCallbacks(&g_sle_uart_connect_cbk);
}

static void sle_uart_client_sample_exchange_info_cbk(uint8_t client_id, uint16_t conn_id, ssap_exchange_info_t *param, errcode_t status)
{
    osal_printk("%s exchange_info_cbk,pair complete client id:%d status:%d\r\n", SLE_CONTROLLER_LOG, client_id, status);
    osal_printk("%s exchange mtu, mtu size: %d, version: %d.\r\n", SLE_CONTROLLER_LOG, param->mtu_size, param->version);
    ssapc_find_structure_param_t find_param = { 0 };
    find_param.type = 1;
    find_param.start_hdl = 1;
    find_param.end_hdl = 0xFFFF;
   int ret =  ssapc_find_structure(client_id, conn_id, &find_param);
   printf("ssapc_find_structure_errcode:%d\r\n",ret);
}

static void sle_uart_client_sample_find_structure_cbk(uint8_t client_id, uint16_t conn_id, ssapc_find_service_result_t *service, errcode_t status)
{
    osal_printk("%s find structure cbk client: %d conn_id:%d status: %d \r\n", SLE_CONTROLLER_LOG, client_id, conn_id, status);
    osal_printk("%s find structure start_hdl:[0x%02x], end_hdl:[0x%02x], uuid len:%d\r\n", SLE_CONTROLLER_LOG, service->start_hdl, service->end_hdl, service->uuid.len);
    g_sle_uart_find_service_result.start_hdl = service->start_hdl;
    g_sle_uart_find_service_result.end_hdl = service->end_hdl;
    memcpy_s(&g_sle_uart_find_service_result.uuid, sizeof(sle_uuid_t), &service->uuid, sizeof(sle_uuid_t));
}

static void sle_uart_client_sample_find_property_cbk(uint8_t client_id, uint16_t conn_id, ssapc_find_property_result_t *property, errcode_t status)
{
    osal_printk("%s sle_uart_client_sample_find_property_cbk, client id: %d, conn id: %d, operate ind: %d, " "descriptors count: %d status:%d property->handle %d\r\n", SLE_CONTROLLER_LOG, client_id, conn_id, property->operate_indication, property->descriptors_count, status, property->handle);
    g_sle_uart_send_param.handle = property->handle;
    g_sle_uart_send_param.type = SSAP_PROPERTY_TYPE_VALUE;
}

static void sle_uart_client_sample_find_structure_cmp_cbk(uint8_t client_id, uint16_t conn_id, ssapc_find_structure_result_t *structure_result, errcode_t status)
{
    unused(conn_id);
    osal_printk("%s sle_uart_client_sample_find_structure_cmp_cbk,client id:%d status:%d type:%d uuid len:%d \r\n", SLE_CONTROLLER_LOG, client_id, status, structure_result->type, structure_result->uuid.len);
}

static void sle_uart_client_sample_write_cfm_cb(uint8_t client_id, uint16_t conn_id, ssapc_write_result_t *write_result, errcode_t status)
{
    osal_printk("%s sle_uart_client_sample_write_cfm_cb, conn_id:%d client id:%d status:%d handle:%02x type:%02x\r\n", SLE_CONTROLLER_LOG, conn_id, client_id, status, write_result->handle, write_result->type);
}

static void sle_uart_client_sample_ssapc_cbk_register(ssapc_notification_callback notification_cb, ssapc_indication_callback indication_cb)
{
    g_sle_uart_ssapc_cbk.exchange_info_cb = sle_uart_client_sample_exchange_info_cbk;
    g_sle_uart_ssapc_cbk.find_structure_cb = sle_uart_client_sample_find_structure_cbk;
    g_sle_uart_ssapc_cbk.ssapc_find_property_cbk = sle_uart_client_sample_find_property_cbk;
    g_sle_uart_ssapc_cbk.find_structure_cmp_cb = sle_uart_client_sample_find_structure_cmp_cbk;
    g_sle_uart_ssapc_cbk.write_cfm_cb = sle_uart_client_sample_write_cfm_cb;
    g_sle_uart_ssapc_cbk.notification_cb = notification_cb;
    g_sle_uart_ssapc_cbk.indication_cb = indication_cb;
    ssapc_register_callbacks(&g_sle_uart_ssapc_cbk);
}

static errcode_t sle_uuid_client_register(void)
{
    errcode_t ret;
    SleUuid app_uuid = {0};
    printf("[uuid client] ssapc_register_client \r\n");
    app_uuid.len = sizeof(g_sle_uuid_app_uuid);
    if (memcpy_s(app_uuid.uuid, app_uuid.len, g_sle_uuid_app_uuid, sizeof(g_sle_uuid_app_uuid)) != EOK)
    {
        return ERRCODE_SLE_FAIL;
    }
    ret = SsapcRegisterClient(&app_uuid, &g_client_id);
    return ret;
}

errcode_t sle_uart_client_send_report_by_handle(const uint8_t *data, uint8_t len)
{
    ssapc_write_param_t param = {0};
    uint8_t receive_buf[0x100] = { 0 };
    param.handle =  g_sle_uart_find_service_result.start_hdl;
    param.type = 0;
    param.data = receive_buf;
    param.data_len = len+1;
    if (memcpy_s(param.data, param.data_len, data, len) != EOK)
    {
        return ERRCODE_SLE_FAIL;
    }
    int ret =SsapWriteReq(g_client_id,g_sle_uart_conn_id, &param);    
    return ret;
}

int uart_sle_client_send_data(uint8_t *data,uint8_t length)
{
    int ret;
    ret = sle_uart_client_send_report_by_handle(data,length);
    return ret ;
}

void ssapc_notification_callbacks(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *data, errcode_t status)
{
    (void)client_id;
    (void)conn_id;
    (void)status;
    data->data[data->data_len -1] = '\0';
    printf("server_send_data: %s\r\n",data->data);
    if(strstr(data->data, "LON:") != NULL)
    {
        strncpy(SLE_longitude, data->data, 16);
        printf(SLE_longitude);
    }
    else if(strstr(data->data, "LAT:") != NULL)
    {
        strncpy(SLE_latitude, data->data, 16);
        printf(SLE_latitude);
    }
}

void ssapc_indication_callbacks(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *data, errcode_t status)
{
    (void)client_id;
    (void)conn_id;
    (void)data;
    (void)status;
}

void sle_init()
{
    uint8_t local_addr[SLE_ADDR_LEN] = { 0x13, 0x67,0x5c, 0x07, 0x00, 0x51 };//0x04-->0x07
    SleAddr local_address;
    local_address.type = 0;
    (void)memcpy_s(local_address.addr, SLE_ADDR_LEN, local_addr, SLE_ADDR_LEN);
    sle_uuid_client_register();
    sle_uart_client_sample_seek_cbk_register();
    sle_uart_client_sample_connect_cbk_register();
    sle_uart_client_sample_ssapc_cbk_register(ssapc_notification_callbacks, ssapc_indication_callbacks);
    EnableSle();
    SleSetLocalAddr(&local_address);    
}


static void *Satellite_task(const char *arg)
{
    (void)arg;
    uart_init_config();
    sle_init();
    OledInit();
    OledFillScreen(0);
    IoTI2cInit(AHT20_I2C_IDX, AHT20_BAUDRATE);
    OledShowString(2, 0, "NearLink WithOH", 1);
    OledShowString(2, 2, "EmergencyRescue", 1);
    OledShowString(42, 4, "Author", 1);
    OledShowString(14, 6, "BI1NDG/BI1NDF", 1);
    Satellite_config();
    TaskMsleep(DELAY_200MS);
    // 初始化GPIO
    IoTGpioInit(BEEP_PIN);
    IoTGpioInit(LED_PIN);
    // 设置引脚功能为MODE_0(GPIO)
    IoSetFunc(SWITCH_PIN, IOT_IO_FUNC_GPIO_10_GPIO);
    IoSetFunc(BEEP_PIN, IOT_IO_FUNC_GPIO_12_GPIO);
    IoSetFunc(LED_PIN, IOT_IO_FUNC_GPIO_14_GPIO);
    // 设置GPIO为输出方向
    IoTGpioSetDir(SWITCH_PIN, IOT_GPIO_DIR_IN);
    IoTGpioRegisterIsrFunc(SWITCH_PIN, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW, OnButtonPressed, NULL);
    IoTGpioSetDir(BEEP_PIN, IOT_GPIO_DIR_OUT);
    IoTGpioSetDir(LED_PIN, IOT_GPIO_DIR_OUT);
    // 配置GPIO引脚号和输出值
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    // 开机功能检测
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_200MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_200MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_200MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_5000MS);
    while(1)
    {
        OledInit();
        OledFillScreen(0);
        IoTI2cInit(AHT20_I2C_IDX, AHT20_BAUDRATE);
        OledShowString(12, 0, "SLE_CONTROLLER", 1);
        //OledShowString(6, 2, "LON:", 1);
        OledShowString(6, 2, CONTROLER_longitude, 1);
        //OledShowString(6, 4, "LAT:", 1);
        OledShowString(6, 4, CONTROLER_latitude, 1);
        OledShowString(54, 6, "1/2", 1);
        TaskMsleep(DELAY_10000MS);
        OledInit();
        OledFillScreen(0);
        OledShowString(24,0, "SLE_BEACON", 1);
        //OledShowString(6, 3, "LON:", 1);
        OledShowString(6, 2, SLE_longitude, 1);
        //OledShowString(6, 5, "LAT:", 1);
        OledShowString(6, 4, SLE_latitude, 1);
        OledShowString(54, 6, "2/2", 1);
        TaskMsleep(DELAY_10000MS);
    }
}

static void SLE_CONTROLLER_entry(void)
{
    osThreadAttr_t attr = {0}; 
    printf("[SLE_CONTROLLER] SLE_CONTROLLER_Entry\r\n"); 
    attr.name = "Satellite_task"; 
    attr.attr_bits = 0U; 
    attr.cb_mem = NULL; 
    attr.cb_size = 0U; 
    attr.stack_mem = NULL; 
    attr.stack_size = 2048 * 10;
    attr.priority = 25;
    
    attr.priority = osPriorityNormal;
    if (osThreadNew((osThreadFunc_t)Satellite_task, NULL, &attr) == NULL) 
    { 
        printf("[Satellite] Falied to create Satellite_task!\r\n"); 
    }
    else  printf("[[Satellite] create Satellite_task]\r\n");
}
SYS_RUN(SLE_CONTROLLER_entry);